﻿/*
 * Matrix4x4.h
 *
 *  Created on: 2011/06/24
 *      Author: naoki
 */

#ifndef INCLUDED_NTENGINE_MATH_MATRIX4X4_H
#define INCLUDED_NTENGINE_MATH_MATRIX4X4_H

namespace NTEngine {
namespace Math {
class Vector3;
class Vector4;
class Matrix3x4;

/**
 * @brief 4x4行列クラス
 *       サポートしているメソッドはあまり多くない
 *       射影変換行列などはこちらで
 */
class Matrix4x4 {
public:
	/**
	 * @brief 最初の数字は行、後ろの数字は列
	 */
	float m11, m12, m13, m14;
	float m21, m22, m23, m24;
	float m31, m32, m33, m34;
	float m41, m42, m43, m44;

	// constructors
	Matrix4x4(){ }
	Matrix4x4( const Matrix4x4& );
	// operators
	void operator*=( const Matrix4x4& );
	void operator*=( const Matrix3x4& );
	bool operator==( const Matrix4x4& ) const;
	bool operator!=( const Matrix4x4& ) const;
	float& operator()( int row, int column );
	float operator()( int row, int column ) const;

	/**
	 * @brief 透視変換行列の生成
	 */
	void setPerspectiveTransform(
		float fov, float w, float h, float nc, float fc, bool zBufferIsLinear = false );

	/**
	 * @brief 正射影行列の生成
	 */
	void setOrthogonalTransform(
		float l, float r, float b, float t, float front, float back );

	/**
	 * @brief view行列を作ってその場で掛け算する
	 */
	void multiplyViewTransform(
		const Vector3& position,
		const Vector3& target,
		const Vector3& up );

	/**
	 * @brief 掛け算の結果をセット
	 */
	void setMul( const Matrix4x4& a, const Matrix3x4& b );

	/**
	 * @brief 単位行列にします
	 */
	void identity();

	/**
	 * @brief Vector3との乗算の結果をVector4に格納
	 */
	void multiply(const Vector3& in, Vector4* out) const;

	/**
	 * @brief 自身の行列式取得
	 */
	float determinant() const;
};

} // namespace Math
} // namespace NTEngine

#endif //
